//
//  MapperTransform.swift
//  DBCA
//
//  Created by mugua on 2024/7/1.
//

import Foundation
import ObjectMapper

public class MapperTransform {
    
    public static var stringValueTransform: TransformOf<String, Any> = TransformOf<String, Any>(fromJSON: { (value) -> String? in
        return Opt.getString(of: value)
    }) { (value) -> String? in
        return Opt.getString(of: value)
    }
    
    public static var intValueTransform: TransformOf<Int, Any> = TransformOf<Int, Any>(fromJSON: { (value) -> Int? in
        return Opt.getInt(of: value)
    }) { (value) -> Int? in
        return Opt.getInt(of: value)
    }
    
    
    public static var boolValueTransform: TransformOf<Bool, Any> = TransformOf<Bool, Any>(fromJSON: { (value) -> Bool? in
        return Opt.getBool(of: value)
    }) { (value) -> Int? in
        return Opt.getInt(of: Opt.getBool(of: value))
    }

    public static var doubleValueTransform: TransformOf<Double, Any> = TransformOf<Double, Any>(fromJSON: { (value) -> Double? in
        return Opt.getDouble(of: value)
    }) { (value) -> Double? in
        return Opt.getDouble(of: value)
    }
    
    
    public static let dateFormatter = { () -> DateFormatter in
        let formatter = DateFormatter()
        formatter.timeZone = TimeZone(identifier: "GMT+08:00")
        formatter.dateFormat = "YYYY-MM-dd HH:mm:ss"
        return formatter
    }()

    public static var dateFromString: TransformOf<Date,String> = TransformOf<Date,String>(fromJSON: { (value) -> Date? in
        guard let string = value else { return nil }
        return dateFormatter.date(from: string)
    }) { (value) -> String? in
        guard let date = value else { return nil }
        return dateFormatter.string(from: date)
    }
    
    public static var dateFromTimestamp: TransformOf<Date, TimeInterval> = TransformOf<Date,TimeInterval>(fromJSON: { (value) -> Date? in
        guard let timestamp = value else { return nil }
        return Date(timeIntervalSince1970: timestamp)
    }) { (value) -> TimeInterval? in
        guard let date = value else { return nil }
        return date.timeIntervalSince1970
    }
}

public class Opt {
    
    public static func getString(of value: Any?) -> String? {
        guard let value = value else { return nil }
        if let number = value as? NSNumber {
            return number.stringValue
        } else {
            return value as? String
        }
    }
    
    public static func getBool(of value: Any?) -> Bool? {
        guard let value = value else { return nil }
        if let str = value as? String {
            return OptHelper.strToBool(str)
        } else {
            let number = value as? NSNumber
            return number?.boolValue
        }
    }
    
    public static func getDouble(of value: Any?) -> Double? {
        guard let value = value else { return nil }
        if let str = value as? String {
            return Double(str)
        } else {
            let number = value as? NSNumber
            return number?.doubleValue
        }
    }
    
    public static func getInt(of value: Any?) -> Int? {
        guard let value = value else { return nil }
        if let str = value as? String {
            return Int(str)
        } else {
            let number = value as? NSNumber
            return number?.intValue
        }
    }
    
    struct OptHelper {
        private static let trueStrSet = Set(arrayLiteral: "yes", "YES", "Yes", "true", "True", "TRUE", "1")
        private static let falseStrSet = Set(arrayLiteral: "no", "NO", "No", "false", "False", "FALSE", "0")

        static func strToBool(_ str: String) -> Bool? {
            return trueStrSet.contains(str) ? true : falseStrSet.contains(str) ? false : nil
        }
    }
    
}
